#include "BlockQueue.hpp"
#include "Task.hpp"

#define NUM 5

void *consumer(void *args)
{
    // 生产者消费者模型————阻塞队列传输数据
    // BQueue::Bloack_Queue<int>* bq = (BQueue::Bloack_Queue<int>*)args;
    // while(true)
    // {
    //     // sleep(2);
    //     int data = 0;
    //     bq->Pop(&data);
    //     std::cout << "consumer take " << data << std::endl;
    // }
    /*-----------------------------------------------------------------*/
    BQueue::Bloack_Queue<MyTask::Task> *bq = (BQueue::Bloack_Queue<MyTask::Task> *)args;
    while (true)
    {
        MyTask::Task t;
        // 1. 拿到数据
        bq->Pop(&t);
        // 2. 处理数据
        t();
    }
}

void *productor(void *args)
{
    // 生产者消费者模型————阻塞队列传输数据
    // BQueue::Bloack_Queue<int>* bq = (BQueue::Bloack_Queue<int>*)args;
    // while(true)
    // {
    //     sleep(1);
    //     int data = rand()%10 + 1;
    //     std::cout << "productor give " << data << std::endl;
    //     bq->Push(data);
    // }
    /*-----------------------------------------------------------------*/
    BQueue::Bloack_Queue<MyTask::Task> *bq = (BQueue::Bloack_Queue<MyTask::Task> *)args;
    std::string ops = "+-*/%";
    while (true)
    {
        // 1.制造数据
        int x = rand() % 20 + 1;
        int y = rand() % 10 + 1;
        char op = ops[rand() % 5];
        MyTask::Task t(x, y, op);
        std::cout << "Productor Push a task:" << x << op << y << "=?" << std::endl;
        // 2.把任务放到阻塞队列
        bq->Push(t);
        sleep(1);
    }
}

int main()
{
    // 生产随机数
    srand((long long)time(nullptr));
    /*-----------------------------------------------------------------*/
    // 生产者消费者模型————阻塞队列传输数据
    // BQueue::Bloack_Queue<int>* bq = new BQueue::Bloack_Queue<int>();
    // pthread_t consumer_id, productor_id;
    // pthread_create(&consumer_id, nullptr, consumer, (void *)bq);
    // pthread_create(&productor_id, nullptr, productor, (void *)bq);

    // pthread_join(consumer_id, nullptr);
    // pthread_join(productor_id, nullptr);
    // return 0;
    /*-----------------------------------------------------------------*/
    // 生产者消费者模型————阻塞队列任务处理
    BQueue::Bloack_Queue<MyTask::Task> *bq = new BQueue::Bloack_Queue<MyTask::Task>();
    // 创建两个线程
    pthread_t consumer_id[NUM], productor_id;
    for (int i = 0; i < NUM; ++i)
    {
        pthread_create(consumer_id + i, nullptr, consumer, (void *)bq);
    }
    pthread_create(&productor_id, nullptr, productor, (void *)bq);

    for (int i = 0; i < NUM; ++i)
    {
        pthread_join(consumer_id[i], nullptr);
    }
    pthread_join(productor_id, nullptr);
    return 0;
    /*-----------------------------------------------------------------*/
}
